package com.house365.im.client.listener;

import java.util.Collection;

import com.house365.core.json.JSONException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.Base64;

import android.content.Intent;
import android.util.Log;
import com.house365.core.constant.CorePreferences;
import com.house365.core.json.JSONArray;
import com.house365.core.json.JSONObject;
import com.house365.im.client.Constants;
import com.house365.im.client.IMManager;
import com.house365.im.client.NamespaceC;
import com.house365.im.client.XmppManager;
import com.house365.im.client.db.MessageDBService;
import com.house365.im.client.dto.AudioData;
import com.house365.im.client.dto.MessageData;
import com.house365.im.client.dto.MessageDto;
import com.house365.im.client.dto.NotificationData;
import com.house365.im.client.util.ActivityUtil;
import com.house365.im.client.util.JIDUtil;
import com.house365.im.client.util.LogUtil;
import com.house365.updown.download.DFile;
import com.house365.updown.download.Downloader.DownloadCompleteListener;

/**
 * This class is the receiver of incoming packets asynchronously.
 * 
 * @modifier Rick Ping
 */
public class MessagePacketListener implements PacketListener {

	private static final String LOGTAG = LogUtil
			.makeLogTag(MessagePacketListener.class);

	private final XmppManager xmppManager;

	public MessagePacketListener(XmppManager xmppManager) {
		this.xmppManager = xmppManager;
	
	}

	@Override
	public void processPacket(Packet packet) {
		Log.d(LOGTAG, "MessagePacketListener.processPacket()...");
		Log.d(LOGTAG, "packet.toXML()=" + packet.toXML());
		Message message = (Message) packet;
		try {
		    Collection<PacketExtension> extensions = message.getExtensions();
	        for (PacketExtension packetExtension : extensions) {
	            if (packetExtension == null) {
	                continue;
	            } else {
	                String namespace = packetExtension.getNamespace();
	                if (namespace == null || "".equals(namespace) || !namespace.startsWith("rick:message")) {
	                    continue;
	                } else {
	                    if (NamespaceC.NAMESPACE_MESSAGE_HISTORY.equals(namespace)) {
	                      //历史记录
	                        handleHistoryMessage(message);
	                    } else if (NamespaceC.NAMESPACE_MESSAGE_TEXT.equals(namespace)) {
	                      //文本消息
	                        handleTextMessage(message);
	                    } else if (NamespaceC.NAMESPACE_MESSAGE_IMAGE.equals(namespace)) {
	                      //图片消息
	                        handleImageMessage(message);
	                    } else if (NamespaceC.NAMESPACE_MESSAGE_VOICE.equals(namespace)) {
	                      //语音消息
	                        handleVoiceMessage(message);
	                    } else if (NamespaceC.NAMESPACE_MESSAGE_DOWNLOADED.equals(namespace)) {
	                        // TODO 暂时没有处理该类型消息
	                    } else if (NamespaceC.NAMESPACE_MESSAGE_ALL.equals(namespace)) {
	                        // TODO 暂时没有处理该类型消息
	                    }
	                }
	            }
	        }
		} catch (Exception e) {
			CorePreferences.ERROR("",e);
		}

	}

    private void handleHistoryMessage(Message message) throws JSONException {
        //save single message to db
        List<MessageDto> messageDtos = new ArrayList<MessageDto>();
        JSONArray array = new JSONArray(message.getBody());
        for(int i =0;i<array.length();i++){
        	JSONObject json = array.getJSONObject(i);
        	final MessageDto messageDto = new MessageDto(json.getLong("starttime"), JIDUtil.getNameOfJID(json.getString("fromuser")), JIDUtil.getNameOfJID(json.getString("touser")),json.getString("subject"), json.getString("message"),MessageDto.STATUS_UNREAD,json.getInt("type"));
        	if(messageDto.getType() == MessageDto.TYPE_VOICE || messageDto.getType() == MessageDto.TYPE_IMG){
        		//语音、图片，需要下载文件
        		//带返回id的效率低一点,需要区别
        		int id = MessageDBService.getDBService(xmppManager.getContext()).saveMessageDtoWithId(messageDto);
        		messageDto.setId(id);
        		IMManager.getIMManager().downloadFile(messageDto,new DownloadCompleteListener() {
        			
        			@Override
        			public void onError(DFile dFile) {
        				// TODO Auto-generated method stub
        				
        			}
        			
        			@Override
        			public void onComplete(DFile dFile) {
        				//notify download success
        				String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        				if(callbackBroadcastAction.length()>0){
        					Intent intent = new Intent(callbackBroadcastAction);
        					intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_DOWNLOADED,messageDto.getFromuser(),messageDto.getTouser(),messageDto.getSubject(),messageDto.getMessage()));
        					xmppManager.getContext().sendBroadcast(intent);
        				}
        			}
        		});
        	}else{
        		MessageDBService.getDBService(xmppManager.getContext()).saveMessageDto(messageDto);
        		messageDtos.add(messageDto);
        	}
        	
        }
        //判断是否在前台，一个看当前页面的根Activity是不是启动页面（桌面启动，菜单页，通知栏启动-通知页面）
        if(ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getRootActivity())
        		||
        		ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getCallbackActivityClassName())
        		){
        	//notify chat
        	Log.d(LOGTAG, "AppOnForeground");
        	String from = message.getFrom();
        	if(xmppManager.getImManager().isNotificationBroadcastEnabled()){
        		String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        		if(callbackBroadcastAction.length()>0){
        			if(!messageDtos.isEmpty()){
        			//提示新
        				xmppManager.getImManager().playSound(AudioData.AUDIO_MESSAGE2);
        			}
        			Intent intent = new Intent(callbackBroadcastAction);
        			intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_HISTORY,message.getFrom(),message.getTo(),message.getSubject(),message.getBody()));
        			xmppManager.getContext().sendBroadcast(intent);
        		}
        		
        	}
        }else{
        	//notify in notification manager
        	if(!messageDtos.isEmpty()){
        	Log.d(LOGTAG, "AppOnBackround ");
        	Notifier notifier = new Notifier(xmppManager);
        	NotificationData notificationData =new NotificationData(new Random().nextInt()+"",xmppManager.getImManager().getAppName(), "你有"+messageDtos.size()+"条新消息",new JSONArray(messageDtos).toString());
        	notifier.notify(notificationData);
        }
        }
        	return;
    }

    private void handleTextMessage(Message message) {
        //save single message to db
        MessageDto messageDto = new MessageDto(System.currentTimeMillis(), JIDUtil.getNameOfJID(message.getFrom()), JIDUtil.getNameOfJID(message.getTo()), message.getSubject(),message.getBody(),MessageDto.STATUS_UNREAD);
        MessageDBService.getDBService(xmppManager.getContext()).saveMessageDto(messageDto);
        //判断是否在前台，一个看当前页面的根Activity是不是启动页面（桌面启动，菜单页，通知栏启动-通知页面）
        	if(ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getRootActivity())
        			||
        			ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getCallbackActivityClassName())
        					){
        		//notify chat
        		Log.d(LOGTAG, "AppOnForeground");
        		String from = message.getFrom();
        		if(xmppManager.getImManager().isNotificationBroadcastEnabled()){
        			String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        			if(callbackBroadcastAction.length()>0){
        				MessageData messageData = new MessageData(NamespaceC.NAMESPACE_MESSAGE_TEXT,message.getFrom(),message.getTo(),message.getSubject(),message.getBody());
        				messageData.setTime(messageDto.getStarttime());
        				//提示新
        				xmppManager.getImManager().playSound(AudioData.AUDIO_MESSAGE2);
        				Intent intent = new Intent(callbackBroadcastAction);
        				intent.putExtra(Constants.NOTIFICATION_DATA,messageData);
        				xmppManager.getContext().sendBroadcast(intent);
        			}
        			
        		}
        	}else{
        		//notify in notification manager
        		Log.d(LOGTAG, "AppOnBackround ");
    			doInAppBackground(message, messageDto);
        	}
        	return;
    }

    private void handleImageMessage(Message message) {
    	if (isOldImage(message)) {
			return;
		}
        //save single message to db
        final MessageDto messageDto = new MessageDto(System.currentTimeMillis(), JIDUtil.getNameOfJID(message.getFrom()), JIDUtil.getNameOfJID(message.getTo()), message.getSubject(),message.getBody(),MessageDto.STATUS_UNREAD,MessageDto.TYPE_IMG);
        int id = MessageDBService.getDBService(xmppManager.getContext()).saveMessageDtoWithId(messageDto);
        messageDto.setId(id);
        IMManager.getIMManager().downloadFile(messageDto,new DownloadCompleteListener() {
        	
        	@Override
        	public void onError(DFile dFile) {
        		// TODO Auto-generated method stub
        		
        	}
        	
        	@Override
        	public void onComplete(DFile dFile) {
        		//notify download success
        		String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        		if(callbackBroadcastAction.length()>0){
        			Intent intent = new Intent(callbackBroadcastAction);
        			intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_DOWNLOADED,messageDto.getFromuser(),messageDto.getTouser(),messageDto.getSubject(),messageDto.getMessage()));
        			xmppManager.getContext().sendBroadcast(intent);
        		}
        	}
        });
        	if(ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getRootActivity()) ||
        			ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getCallbackActivityClassName())){
        		//notify chat
        		Log.d(LOGTAG, "AppOnForeground");
        		String from = message.getFrom();
        		if(xmppManager.getImManager().isNotificationBroadcastEnabled()){
        			String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        			if(callbackBroadcastAction.length()>0){
        				//提示新
        				xmppManager.getImManager().playSound(AudioData.AUDIO_MESSAGE2);
        				Intent intent = new Intent(callbackBroadcastAction);
        				intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_IMAGE,message.getFrom(),message.getTo(),message.getSubject(),message.getBody()));
        				xmppManager.getContext().sendBroadcast(intent);
        			}
        			
        		}
        	}else{
        		//notify in notification manager
        		Log.d(LOGTAG, "AppOnBackround ");
        		doInAppBackground(message, messageDto);
        	}
        	return;
    }

    private void handleVoiceMessage(Message message) {
        //save single message to db
        final MessageDto messageDto = new MessageDto(System.currentTimeMillis(), JIDUtil.getNameOfJID(message.getFrom()), JIDUtil.getNameOfJID(message.getTo()), message.getSubject(),message.getBody(),MessageDto.STATUS_UNREAD,MessageDto.TYPE_VOICE);
        int id = MessageDBService.getDBService(xmppManager.getContext()).saveMessageDtoWithId(messageDto);
        messageDto.setId(id);
        IMManager.getIMManager().downloadFile(messageDto,new DownloadCompleteListener() {
        	
        	@Override
        	public void onError(DFile dFile) {
        		// TODO Auto-generated method stub
        		
        	}
        	
        	@Override
        	public void onComplete(DFile dFile) {
        		//notify download success
        		String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        		if(callbackBroadcastAction.length()>0){
        			Intent intent = new Intent(callbackBroadcastAction);
        			intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_DOWNLOADED,messageDto.getFromuser(),messageDto.getTouser(),messageDto.getSubject(),messageDto.getMessage()));
        			xmppManager.getContext().sendBroadcast(intent);
        		}
        	}
        });
        	if(ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getRootActivity())||
        			ActivityUtil.isAppOnForeground(xmppManager.getContext(), xmppManager.getImManager().getCallbackActivityClassName())){
        		//notify chat
        		Log.d(LOGTAG, "AppOnForeground");
        		String from = message.getFrom();
        		if(xmppManager.getImManager().isNotificationBroadcastEnabled()){
        			String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
        			if(callbackBroadcastAction.length()>0){
        				//提示新
        				xmppManager.getImManager().playSound(AudioData.AUDIO_MESSAGE2);
        				Intent intent = new Intent(callbackBroadcastAction);
        				intent.putExtra(Constants.NOTIFICATION_DATA,new MessageData(NamespaceC.NAMESPACE_MESSAGE_VOICE,message.getFrom(),message.getTo(),message.getSubject(),message.getBody()));
        				xmppManager.getContext().sendBroadcast(intent);
        			}
        			
        		}
        	}else{
        		//notify in notification manager
        		Log.d(LOGTAG, "AppOnBackround ");
        		doInAppBackground(message, messageDto);
        	}
        	return;
    }
    
    private void doInAppBackground(Message message, MessageDto messageDto) {
    	Notifier notifier = new Notifier(xmppManager);
		NotificationData notificationData =new NotificationData(new Random().nextInt()+"", xmppManager.getImManager().getAppName(),"你有1条新信息", new JSONObject(messageDto).toString());
		notificationData.setUri(message.getBody());
		notifier.notify(notificationData);
		
		MessageData messageData = new MessageData(NamespaceC.NAMESPACE_MESSAGE_TEXT,message.getFrom(),message.getTo(),message.getSubject(),message.getBody());
		messageData.setTime(messageDto.getStarttime());
		String callbackBroadcastAction = xmppManager.getImManager().getCallbackBrocastAction();
		if(callbackBroadcastAction.length()>0){
			Intent intent = new Intent(callbackBroadcastAction);
			intent.putExtra(Constants.NOTIFICATION_DATA,messageData);
			xmppManager.getContext().sendBroadcast(intent);
		}
    }
    
    private boolean isOldImage(Message message) {
    	byte[] data = Base64.decode(message.getBody());
    	return data != null; 
    }

}
